<?php

namespace App\Http\Controllers\Api;

use App\Models\Department;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;

class DepartmentController extends BaseController
{
    /**
     * 获取部门树形结构
     */
    public function tree(Request $request)
    {
        try {
            // 使用Laravel的嵌套预加载来构建树形结构
            $departments = Department::active()
                ->with([
                    'manager',
                    'children' => function ($query) {
                        $query->active()->with(['manager', 'children']);
                    }
                ])
                ->whereNull('parent_id') // 只获取根部门
                ->orderBy('sort_order')
                ->orderBy('name')
                ->get();

            return $this->success($departments, '获取部门树形结构成功');
        } catch (\Exception $e) {
            return $this->error('获取部门树形结构失败：' . $e->getMessage());
        }
    }

    /**
     * 获取部门列表
     */
    public function index(Request $request)
    {
        try {
            $query = Department::with(['manager', 'parent', 'children']);

            // 搜索条件
            if ($request->has('search')) {
                $search = $request->search;
                $query->where(function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('code', 'like', "%{$search}%")
                      ->orWhere('description', 'like', "%{$search}%");
                });
            }

            // 状态筛选
            if ($request->has('status')) {
                $query->where('status', $request->status);
            }

            // 层级筛选
            if ($request->has('level')) {
                $query->byLevel($request->level);
            }

            // 父部门筛选
            if ($request->has('parent_id')) {
                if ($request->parent_id === 'null') {
                    $query->root();
                } else {
                    $query->childrenOf($request->parent_id);
                }
            }

            // 分页
            $perPage = $request->get('per_page', 15);
            $departments = $query->paginate($perPage);

            return $this->paginate($departments, '获取部门列表成功');
        } catch (\Exception $e) {
            return $this->error('获取部门列表失败：' . $e->getMessage());
        }
    }

    /**
     * 获取部门详情
     */
    public function show(Department $department)
    {
        try {
            $department->load([
                'manager',
                'parent',
                'children',
                'employees' => function ($query) {
                    $query->active()->with(['positionInfo', 'user']);
                },
            ]);

            return $this->success($department, '获取部门详情成功');
        } catch (\Exception $e) {
            return $this->error('获取部门详情失败：' . $e->getMessage());
        }
    }

    /**
     * 创建部门
     */
    public function store(Request $request)
    {
        try {
            $data = $this->validateRequest($request, [
                'code' => 'required|string|max:50|unique:departments',
                'name' => 'required|string|max:100',
                'parent_id' => 'nullable|exists:departments,id',
                'manager_id' => 'nullable|exists:users,id',
                'description' => 'nullable|string|max:500',
                'phone' => 'nullable|string|max:20',
                'email' => 'nullable|email|max:100',
                'address' => 'nullable|string|max:500',
                'establishment_date' => 'nullable|date',
                'budget' => 'nullable|numeric|min:0',
                'sort_order' => 'nullable|integer|min:0',
                'notes' => 'nullable|string',
            ]);

            // 获取所有输入数据（包括可选字段）
            $input = $request->all();

            // 计算部门层级
            $level = 1;
            if (isset($data['parent_id']) && $data['parent_id']) {
                $parent = Department::find($data['parent_id']);
                $level = $parent->level + 1;
            }

            // 创建部门
            $department = Department::create([
                'code' => $data['code'],
                'name' => $data['name'],
                'parent_id' => $data['parent_id'] ?? $input['parent_id'] ?? null,
                'level' => $level,
                'manager_id' => $data['manager_id'] ?? $input['manager_id'] ?? null,
                'description' => $data['description'] ?? $input['description'] ?? null,
                'phone' => $data['phone'] ?? $input['phone'] ?? null,
                'email' => $data['email'] ?? $input['email'] ?? null,
                'address' => $data['address'] ?? $input['address'] ?? null,
                'establishment_date' => $data['establishment_date'] ?? $input['establishment_date'] ?? null,
                'budget' => $data['budget'] ?? $input['budget'] ?? 0,
                'current_budget' => $data['budget'] ?? $input['budget'] ?? 0,
                'sort_order' => $data['sort_order'] ?? $input['sort_order'] ?? 0,
                'status' => 'active',
                'notes' => $data['notes'] ?? $input['notes'] ?? null,
            ]);

            // 记录操作日志
            $this->logOperation('create', 'department', [
                'department_id' => $department->id,
                'code' => $department->code,
                'name' => $department->name,
            ]);

            $department->load(['manager', 'parent']);

            return $this->success($department, '创建部门成功', 201);
        } catch (\Illuminate\Validation\ValidationException $e) {
            // 处理验证错误，提供用户友好的错误信息
            $errors = $e->errors();
            $friendlyErrors = [];

            foreach ($errors as $field => $messages) {
                foreach ($messages as $message) {
                    switch ($field) {
                        case 'code':
                            if (str_contains($message, 'unique')) {
                                $friendlyErrors[] = '部门编码已存在，请使用其他编码';
                            } elseif (str_contains($message, 'required')) {
                                $friendlyErrors[] = '部门编码不能为空';
                            } elseif (str_contains($message, 'max')) {
                                $friendlyErrors[] = '部门编码长度不能超过50个字符';
                            } else {
                                $friendlyErrors[] = '部门编码格式不正确';
                            }
                            break;
                        case 'name':
                            if (str_contains($message, 'required')) {
                                $friendlyErrors[] = '部门名称不能为空';
                            } elseif (str_contains($message, 'max')) {
                                $friendlyErrors[] = '部门名称长度不能超过100个字符';
                            } else {
                                $friendlyErrors[] = '部门名称格式不正确';
                            }
                            break;
                        case 'parent_id':
                            if (str_contains($message, 'exists')) {
                                $friendlyErrors[] = '选择的父部门不存在';
                            } else {
                                $friendlyErrors[] = '父部门选择不正确';
                            }
                            break;
                        case 'manager_id':
                            if (str_contains($message, 'exists')) {
                                $friendlyErrors[] = '选择的部门负责人不存在';
                            } else {
                                $friendlyErrors[] = '部门负责人选择不正确';
                            }
                            break;
                        case 'email':
                            $friendlyErrors[] = '邮箱格式不正确';
                            break;
                        case 'budget':
                            if (str_contains($message, 'min')) {
                                $friendlyErrors[] = '预算金额不能小于0';
                            } else {
                                $friendlyErrors[] = '预算金额格式不正确';
                            }
                            break;
                        case 'sort_order':
                            if (str_contains($message, 'min')) {
                                $friendlyErrors[] = '排序号不能小于0';
                            } else {
                                $friendlyErrors[] = '排序号格式不正确';
                            }
                            break;
                        default:
                            $friendlyErrors[] = $message;
                            break;
                    }
                }
            }

            $errorMessage = implode('；', $friendlyErrors);
            return $this->error('创建部门失败：' . $errorMessage, 422, $errors);
        } catch (\Exception $e) {
            // 处理其他异常
            return $this->error('创建部门失败：服务器内部错误，请稍后重试', 500);
        }
    }

    /**
     * 更新部门信息
     */
    public function update(Request $request, Department $department)
    {
        try {
            $data = $this->validateRequest($request, [
                'code' => ['sometimes', 'required', 'string', 'max:50', Rule::unique('departments')->ignore($department->id)],
                'name' => 'sometimes|required|string|max:100',
                'parent_id' => 'sometimes|nullable|exists:departments,id',
                'manager_id' => 'sometimes|nullable|exists:users,id',
                'description' => 'sometimes|nullable|string|max:500',
                'phone' => 'sometimes|nullable|string|max:20',
                'email' => 'sometimes|nullable|email|max:100',
                'address' => 'sometimes|nullable|string|max:500',
                'establishment_date' => 'sometimes|nullable|date',
                'budget' => 'sometimes|nullable|numeric|min:0',
                'current_budget' => 'sometimes|nullable|numeric|min:0',
                'sort_order' => 'sometimes|nullable|integer|min:0',
                'status' => 'sometimes|required|in:active,inactive,dissolved',
                'notes' => 'sometimes|nullable|string',
            ]);

            // 如果更新父部门，需要重新计算层级
            if (isset($data['parent_id']) && $data['parent_id'] !== $department->parent_id) {
                $level = 1;
                if ($data['parent_id']) {
                    $parent = Department::find($data['parent_id']);
                    $level = $parent->level + 1;
                }
                $data['level'] = $level;
            }

            $department->update($data);

            // 记录操作日志
            $this->logOperation('update', 'department', [
                'department_id' => $department->id,
                'changes' => $data,
            ]);

            $department->load(['manager', 'parent']);

            return $this->success($department, '更新部门信息成功');
        } catch (\Illuminate\Validation\ValidationException $e) {
            // 处理验证错误，提供用户友好的错误信息
            $errors = $e->errors();
            $friendlyErrors = [];

            foreach ($errors as $field => $messages) {
                foreach ($messages as $message) {
                    switch ($field) {
                        case 'code':
                            if (str_contains($message, 'unique')) {
                                $friendlyErrors[] = '部门编码已存在，请使用其他编码';
                            } elseif (str_contains($message, 'required')) {
                                $friendlyErrors[] = '部门编码不能为空';
                            } elseif (str_contains($message, 'max')) {
                                $friendlyErrors[] = '部门编码长度不能超过50个字符';
                            } else {
                                $friendlyErrors[] = '部门编码格式不正确';
                            }
                            break;
                        case 'name':
                            if (str_contains($message, 'required')) {
                                $friendlyErrors[] = '部门名称不能为空';
                            } elseif (str_contains($message, 'max')) {
                                $friendlyErrors[] = '部门名称长度不能超过100个字符';
                            } else {
                                $friendlyErrors[] = '部门名称格式不正确';
                            }
                            break;
                        case 'parent_id':
                            if (str_contains($message, 'exists')) {
                                $friendlyErrors[] = '选择的父部门不存在';
                            } else {
                                $friendlyErrors[] = '父部门选择不正确';
                            }
                            break;
                        case 'manager_id':
                            if (str_contains($message, 'exists')) {
                                $friendlyErrors[] = '选择的部门负责人不存在';
                            } else {
                                $friendlyErrors[] = '部门负责人选择不正确';
                            }
                            break;
                        case 'email':
                            $friendlyErrors[] = '邮箱格式不正确';
                            break;
                        case 'budget':
                        case 'current_budget':
                            if (str_contains($message, 'min')) {
                                $friendlyErrors[] = '预算金额不能小于0';
                            } else {
                                $friendlyErrors[] = '预算金额格式不正确';
                            }
                            break;
                        case 'sort_order':
                            if (str_contains($message, 'min')) {
                                $friendlyErrors[] = '排序号不能小于0';
                            } else {
                                $friendlyErrors[] = '排序号格式不正确';
                            }
                            break;
                        case 'status':
                            $friendlyErrors[] = '部门状态值不正确，只能是正常、停用或撤销';
                            break;
                        default:
                            $friendlyErrors[] = $message;
                            break;
                    }
                }
            }

            $errorMessage = implode('；', $friendlyErrors);
            return $this->error('更新部门信息失败：' . $errorMessage, 422, $errors);
        } catch (\Exception $e) {
            // 处理其他异常
            return $this->error('更新部门信息失败：服务器内部错误，请稍后重试', 500);
        }
    }

    /**
     * 删除部门
     */
    public function destroy(Department $department)
    {
        try {
            // 检查是否有子部门
            if ($department->children()->count() > 0) {
                return $this->error('该部门有子部门，无法删除');
            }

            // 检查是否有员工
            if ($department->employees()->count() > 0) {
                return $this->error('该部门还有员工，无法删除');
            }

            $department->delete();

            // 记录操作日志
            $this->logOperation('delete', 'department', [
                'department_id' => $department->id,
                'code' => $department->code,
                'name' => $department->name,
            ]);

            return $this->success(null, '删除部门成功');
        } catch (\Exception $e) {
            return $this->error('删除部门失败：' . $e->getMessage());
        }
    }

    /**
     * 获取部门统计信息
     */
    public function statistics(Request $request)
    {
        try {
            $stats = [
                'total_departments' => Department::count(),
                'active_departments' => Department::active()->count(),
                'by_level' => Department::selectRaw('level, COUNT(*) as count')
                    ->groupBy('level')
                    ->orderBy('level')
                    ->get(),
                'by_status' => Department::selectRaw('status, COUNT(*) as count')
                    ->groupBy('status')
                    ->get(),
                'with_manager' => Department::whereNotNull('manager_id')->count(),
                'total_budget' => Department::sum('budget'),
                'average_budget' => Department::avg('budget'),
            ];

            return $this->success($stats, '获取部门统计信息成功');
        } catch (\Exception $e) {
            return $this->error('获取部门统计信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取部门及其子部门的所有员工
     */
    public function employees(Department $department, Request $request)
    {
        try {
            $departmentIds = [$department->id, ...$department->getChildrenIds()];

            $employees = \App\Models\Employee::with(['user', 'positionInfo'])
                ->whereIn('department_id', $departmentIds)
                ->active()
                ->paginate($request->get('per_page', 15));

            return $this->paginate($employees, '获取部门员工列表成功');
        } catch (\Exception $e) {
            return $this->error('获取部门员工列表失败：' . $e->getMessage());
        }
    }

    /**
     * 更新部门预算
     */
    public function updateBudget(Request $request, Department $department)
    {
        try {
            $data = $this->validateRequest($request, [
                'budget' => 'required|numeric|min:0',
                'current_budget' => 'sometimes|numeric|min:0',
            ]);

            $department->update($data);

            return $this->success($department, '更新部门预算成功');
        } catch (\Exception $e) {
            return $this->error('更新部门预算失败：' . $e->getMessage());
        }
    }
}
